﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Aquasoft.Iszr.Proxy.WebServices;
using Aquasoft.Iszr.Proxy.WebServices.Interfaces;

namespace Aquasoft.Iszr.Proxy.ZadostInfoUtils
{
    /// <summary>
    /// Obecný předek pro automatické vyplňování ZadostInfo na ISZR requestech.
    /// </summary>
    public abstract class IszrZadostInfoScopeBase : IDisposable
    {
        private readonly IszrZadostInfoScopeBase __parent;
        private bool __isRegistered;

        public IszrZadostInfoScopeBase Parent
        {
            get { return __parent; }
        }

        protected IszrZadostInfoScopeBase()
        {
            __parent = IszrZadostInfoManager.RegisterScope(this);
            __isRegistered = true;
        }

        public ZadostInfoType GetZadostInfo(ISzrZadostInfo request)
        {
            if (request == null)
                throw new ArgumentNullException("request");

            var zadostInfo = CreateZadostInfo(request);
            if (zadostInfo == null)
                throw new ApplicationException("ZadostInfo is null.");

            SetupZadostInfo(request, zadostInfo);

            var zadostInfoIszr = zadostInfo as ZadostInfoIszrType;
            if (zadostInfoIszr != null)
                SetupZadostInfoIszr(request, zadostInfoIszr);

            SetupZadostInfoUzivatel(request, zadostInfo);

            return zadostInfo;
        }

        /// <summary>
        /// Vytvoří instanci ZadostInfo
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        protected virtual ZadostInfoType CreateZadostInfo(ISzrZadostInfo request)
        {
            ZadostInfoType zadostInfo;
            if (request is ISzrZadostInfoIszr)
                zadostInfo = new ZadostInfoIszrType();
            else
                zadostInfo = new ZadostInfoType();

            return zadostInfo;
        }

        /// <summary>
        /// Naplní instanci ZadostInfo
        /// </summary>
        /// <param name="request"></param>
        /// <param name="zadostInfo"></param>
        protected virtual void SetupZadostInfo(ISzrZadostInfo request, ZadostInfoType zadostInfo)
        {
            zadostInfo.CasZadosti = DateTime.Now;
            zadostInfo.AgendaZadostId = Guid.NewGuid().ToString("D");
        }

        /// <summary>
        /// V případě, že ZadostInfo je typu ZadostInfoIszrType, volá se tato metoda pro možnost doplnění.
        /// </summary>
        /// <param name="request"></param>
        /// <param name="zadostInfo"></param>
        protected virtual void SetupZadostInfoIszr(ISzrZadostInfo request, ZadostInfoIszrType zadostInfo)
        { 
        }

        /// <summary>
        /// Naplní element uživatel. Ve výchozím nastavení volá IszrZadostInfoManager.GetCurrentIszrUzivatel().
        /// </summary>
        /// <param name="request"></param>
        /// <param name="zadostInfo"></param>
        protected virtual void SetupZadostInfoUzivatel(ISzrZadostInfo request, ZadostInfoType zadostInfo)
        {
            zadostInfo.Uzivatel = IszrZadostInfoManager.GetCurrentIszrUzivatel();
        }

        /// <summary>
        /// Volá se při dispose. Odregistrování scope probíhá po volání této metody.
        /// </summary>
        protected virtual void OnDispose()
        {
        }

        #region IDisposable Members

        public void Dispose()
        {
            OnDispose();
            if (__isRegistered)
            {
                IszrZadostInfoManager.RegisterScope(__parent);
                __isRegistered = false;
            }
        }

        #endregion
    }
}
